/**
 * \brief Implementação de uma HashMap Abstracta
 *
 * Resolve as colisões utilizando a metodologia chaining.
 */
# ifndef HASHMAP_CHAINING_DEF
# define HASHMAP_CHAINING_DEF

# include "hash.h"
# include "../lists/linked-list.h"
# include <stdlib.h>

typedef struct {
        LinkedList **list;
        int size;
        hashFunction hash;
        equalFunction eq; // Para comparar Keys
} ChainingHashMap;

/**
 * \brief Cria uma nova Tabela
 * \param size Tamanho da hash
 * \return Nova tabela sem função de hash nem eq.
 *
 * Pode crashar (mesmo erro de sempre - malloc)
 */
ChainingHashMap * newChainingHashMap (int size);
/**
 * \brief Adiciona um par à Tabela
 * \param map Tabela
 * \param key Chave
 * \param data Informação (não é necessário ter a chave incluida)
 * \return 0 se algo falhar, 1 se correr tudo bem
 */
int putChaining(ChainingHashMap *map, void *key, void *data); // 0 se nao conseguir
/**
 * \brief Retira a informação da Tabela
 * \param map Tabela
 * \param key Chave
 * \return NULL se não tiver, ou a Informação
 */
void * getChaining(ChainingHashMap *map, void *key); // NULL se não conseguir
/**
 * \brief Remove uma Informação
 * \param map Tabela
 * \param key Chave do Elemento em causa
 * \return 0 se não conseguir 1 se correr bem
 */
int removeChaining(ChainingHashMap *map, void *key); // 0 se nao conseguiu

/**
 * \brief Da a lista de chaves da tabela
 * \param map Tabela
 * \return Lista de chaves
 */
LinkedList * keySetChaining (ChainingHashMap *map);

/**
 * \brief Liberta toda a memoria dinamica alocada para esta estrutura
 * \param map a tabela de hash
 * \description
 *
 * Apenas liberda a estrutura tudo o resto é mantido
 */
void freeChainingHashMap (ChainingHashMap *map);
# endif
